﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include "GcmpModelInterface.h"
#include "IDbObject.h"
#include "Box2d.h"
#include "TiltBox3d.h"
#include "Matrix4d.h"
#include "Coordinate3d.h"

namespace gcmp 
{
    enum CameraParamType
    {
        Perspective,        ///< 透视投影
        Ortho               ///< 正交投影
    };
    struct CameraParamStruct
    {
        CameraParamType Type = CameraParamType::Ortho; //相机类型，透视投影/正交投影
        Vector3d Position = Vector3d(0, 0, 0);              //相机位置
        Vector3d Direction = Vector3d(0, 0, -1);        //方向
        Vector3d UpDirection = Vector3d(0, 1, 0);      //上方向
        double AspectRatio = 1;                 //视口宽高比
        double NearDist = 0;                    //近裁剪面距离
        double FarDist = 1;                     //远裁剪面距离
        double FieldOfView = 1;                 //相机张角，仅透视投影有效
        double OrthoWindowHeight = 100;         //观察窗口高度，仅正交模式有效

        bool Isvalid() const
        {
            if (Type == CameraParamType::Ortho
                && Position == Vector3d(0, 0, 0)
                && Direction == Vector3d(0, 0, -1)
                && UpDirection == Vector3d(0, 1, 0)
                && MathUtils::IsEqual(AspectRatio, 1)
                && MathUtils::IsEqual(NearDist, 0)
                && MathUtils::IsEqual(FarDist, 1)
                && MathUtils::IsEqual(FieldOfView, 1)
                && MathUtils::IsEqual(OrthoWindowHeight, 100))
            {
                return false;
            }
            else
                return true;
        }
    };

    /// \brief 视口相机参数接口类
    FINAL_INTERFACE class GCMP_MODEL_INTERFACE_EXPORT IDrawingViewportCamera : public IDbObject
    {
        DEFINE_CAST_DERIVED(gcmp::IDrawingViewportCamera, gcmp::IDbObject);
     public:
         /// \brief  获取相机参数
         /// \return       CameraParamStruct
         virtual CameraParamStruct GetCameraParameters() const = 0;

         /// \brief  获取视口的显示范围
         /// \param[out]   double& dWidth
         /// \param[out]   double& dHeight
         virtual void GetViewRange(double& dWidth,double& dHeight) const = 0;

         /// \brief 
         /// \return       Box2d
         virtual Box2d GetViewRange() const =0;

         /// \brief 获取相机投影点坐标系(以相机投影点为原点)
         /// \return       Coordinate3d
         virtual Coordinate3d GetCameraProjectionCoord() const =0;

         /// \brief 获取投影面坐标系
         /// \return       Coordinate3d
         virtual Coordinate3d GetProjectionCoord() const = 0;

         /// \brief 获取视口对应的显示显示范围
         /// \return       TiltBox3d
         virtual TiltBox3d GetViewRangeTiltBox() const =0;

         /// \brief  更新相机位置
         /// \param[in]    const Vector2d& offsetCenter 相机位置偏移值
         virtual void UpdatePosition(const Vector2d& offsetCenter) =0;

         /// \brief  更新视口范围的宽度,和高度
         /// \param[in]    double offsetLenght  宽度偏移值
         /// \param[in]    double offsetHeight
         virtual void UpdateWidthtAndHeight(double offsetWidth, double offsetHeight) =0;

         /// \brief 更新视口范围的宽度,和高度
         /// \param[in]    double dScale  缩放比
         virtual void UpdateWidthtAndHeight(double dScale) =0;

         /// \brief  更新视口相机参数
         /// \param[in]    const Vector3d& centerOffset  相机点偏移值
         /// \param[in]    double offsetWidth  宽度偏移值 
         /// \param[in]    double offsetHeight 高度偏移值
         virtual void UpdateCameraParameters(const Vector3d& centerOffset, double offsetWidth, double offsetHeight) =0;
    };
}
